/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.webapp.taglib.core.logic;

import com.blandware.atleap.webapp.util.core.GlobalProperties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.taglib.TagUtils;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * <p>Retrieves value of global property (either static or dynamic) and exports
 * it to the specified scope.</p>
 * <p>
 * If no value could be found for global property with given name, then, if
 * <code>defaultValue</code> is specified, it will be used instead, otherwise
 * (nothing found and no default value) the result will be <code>null</code>.
 * If default value is used, firstly its string value is obtained through its
 * <code>toString()</code> method. If <code>type</code> is <em>integer</em>,
 * string value is parsed to get <code>Integer</code> value.
 * </p>
 * <p>
 * Allowed attributes are:
 * <ul>
 * <li>
 * <b>name</b> - this is required; it's the name of global property to export
 * </li>
 * <li>
 * <b>defaultValue</b> - default value to use when no global property value was
 * found. Its <code>toString()</code> method is called and for <em>integer</em>
 * type it's parsed to get <code>Integer</code> value
 * </li>
 * <li>
 * <b>type</b> - type of property: <em>string</em> or <em>integer</em>.
 * If it's neither <em>string</em> nor <em>integer</em>, it's treated as
 * <em>string</em>. This attribute is case-insensitive.
 * </li>
 * <li>
 * <b>var</b> - this is required; it's name of variable to export result
 * </li>
 * <li>
 * <b>scope</b> - scope of variable to export result
 * </li>
 * </ul>
 * <p><a href="GlobalPropertyTag.java.html"><i>View Source</i></a></p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.2 $ $Date: 2006/08/03 10:08:24 $
 * @jsp.tag name="globalProperty"
 * body-content="empty"
 */
public class GlobalPropertyTag extends SimpleTagSupport {

	protected transient final Log log = LogFactory.getLog(GlobalPropertyTag.class);

	/**
	 * Name of property to retrieve value of
	 */
	protected String name;

	/**
	 * Default value to use
	 */
	protected Object defaultValue;

	/**
	 * Type of property: <code>string<code> or <code>integer</code>.
	 * Default is <code>string</code>
	 */
	protected String type;

	/**
	 * Name of variable to export value to
	 */
	protected String var;

	/**
	 * Scope to export variable to
	 */
	protected String scope;

	/**
     * Returns name of the global property
     *
	 * @return name
     * @see #name
	 * @jsp.attribute required="true"
	 * rtexprvalue="true"
	 * type="java.lang.String"
	 * description="Name of property to retrieve value of"
	 */
	public String getName() {
		return name;
	}

    /**
     * Sets name of the global property
     *
     * @param name name to set
     * @see #name
     */
	public void setName(String name) {
		this.name = name;
	}

	/**
     * Returns default value
     *
	 * @return default value
     * @see #defaultValue
	 * @jsp.attribute required="false"
	 * rtexprvalue="true"
	 * type="java.lang.String"
	 * description="Default value to use"
	 */
	public Object getDefaultValue() {
		return defaultValue;
	}

    /**
     * Sets default value
     *
     * @param defaultValue default value to set
     */
	public void setDefaultValue(Object defaultValue) {
		this.defaultValue = defaultValue;
	}

	/**
     * Returns type of global property
     *
	 * @return type
     * @see #type
	 * @jsp.attribute required="false"
	 * rtexprvalue="true"
	 * type="java.lang.String"
	 * description="Type of property: string or integer. Default is integer"
	 */
	public String getType() {
		return type;
	}

    /**
     * Sets type of global property
     *
     * @param type type to set
     * @see #type
     */
	public void setType(String type) {
		this.type = type;
	}

	/**
     * Returns name of variable
     *
	 * @return name of variable
     * @see #var
	 * @jsp.attribute required="true"
	 * rtexprvalue="true"
	 * type="java.lang.String"
	 * description="Name of variable to export formatted date"
	 */
	public String getVar() {
		return var;
	}

    /**
     * Sets name of variable
     *
     * @param var name of variable to set
     * @see #var
     */
	public void setVar(String var) {
		this.var = var;
	}

    /**
     * Returns variable scope
     *
     * @return variable scope
     * @see #scope
	 * @jsp.attribute required="false"
	 * rtexprvalue="true"
	 * type="java.lang.String"
	 * description="Scope to export variable to"
     */
	public String getScope() {
		return scope;
	}

	/**
     * Sets variable scope
     *
	 * @param scope variable scope to set
     * @see #scope
	 */
	public void setScope(String scope) {
		this.scope = scope;
	}

    /**
     * Processes the tag
     *
     * @throws JspException
     */
	public void doTag() throws JspException {

		PageContext pageContext = (PageContext) getJspContext();

		if ( !"string".equalsIgnoreCase(type) && !"integer".equalsIgnoreCase(type) ) {
			type = "string";
		}

		GlobalProperties globalProperties = GlobalProperties.getInstance(pageContext.getServletContext());

		Object property = null;

		if ( type.equalsIgnoreCase("string") ) {
			property = globalProperties.getString(name, defaultValue != null ? defaultValue.toString() : null);
		} else {
			String s = defaultValue != null ? defaultValue.toString() : null;
			Integer value = null;
			if ( s != null && s.length() > 0 ) {
				try {
					value = Integer.valueOf(s);
				} catch ( NumberFormatException e ) {
					throw new JspException("Value '" + s + "' cannot be converted to java.lang.Integer");
				}
			}
			property = globalProperties.getInteger(name, value);
		}

		int varScope = PageContext.PAGE_SCOPE;
		if ( scope != null ) {
			varScope = TagUtils.getInstance().getScope(scope);
		}
		pageContext.setAttribute(var, property, varScope);
	}

}
